Once the code and algorithm are understood, the next question is how to best test the code. Ideally the original implementer should leave behind code and documentation for this purpose, but usually what we have is the final code and a paper. What other kinds of artifacts (code, documentation, data, test cases, etc.) should an implementer produce to help with this?
In an attempt to address these issues, I created a repository with various Python scripts and Jupyter (IPython) notebooks covering different algorithms used in a Quantum Monte Carlo code. The repository is here: https://github.com/markdewing/qmc_algorithms
Some more benefits and goals of these scripts include
Ease of comprehension
Notebooks show the derivations and demonstrate the algorithm working in a simpler context. These aim to be a bridge between the paper or text description of an algorithm and the final production implementation.
Symbolic Representation
Represent the various equations in a more symbolic form. This allows mathematics-aware transformations, such as taking derivatives. See the Jastrow factor in Wavefunctions/Pade_Jastrow.ipynb for an example. Also the wavefunctions and expressions for the energy in Variational/Variational_Hydrogen.ipynb and Variational/Variational_Helium.ipynb.
Testing
These scripts can be used for testing in several ways. One is to evaluate the expressions at a single point to check values in unit tests.
Eventually the symbolic or script representation should be compared against the code for a wider range of values and parameters. This is similar to property-based testing in software engineering, but there are a couple of issues to address. The first is infrastructure support. Most property-based testing frameworks focus on integer parameters, like array lengths, and not so much on floating point values. A second issue is cross-language coding. In our case, the script representation is in Python and the code to test is in C++.
Also for testing, simpler or slower algorithms can be used to verify more complex algorithms. For example, the repository contains a python script for Ewald summation (LongRange/ewald_sum.py) that uses the standard break-up between short and long range pieces. QMCPACK optimizes this split between the short and long range pieces, but the result should still be the same, up to some error tolerance.
Code generation
Ultimately, code generation can be used to connect the symbolic form to the executable code. This will a require a maintainable mechanism for doing the code generation (it's easy to start doing code generation, but there can be problems with scaling it and keeping it neat, clean, and understandable. ) The previous step - using the symbolic forms for testing - seems like an easier intermediate path, and is better suited for testing existing code.
Summary
This is an experiment in creating artifacts that enhance comprehension and testing of scientific programs. Take a look at the repository ( https://github.com/markdewing/qmc_algorithms ) and see if you find it useful.